package edu.langnan.xiaoli.service.impl;

import edu.langnan.xiaoli.core.domain.ActivityDO;
import edu.langnan.xiaoli.core.dto.ActivityDTO;
import edu.langnan.xiaoli.core.dto.ActivityInfoDTO;
import edu.langnan.xiaoli.exception.activity.*;
import edu.langnan.xiaoli.mapper.ActivityMapper;
import edu.langnan.xiaoli.redis.RedisCache;
import edu.langnan.xiaoli.service.ActivityService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author cql
 */
@Service
public class ActivityServiceImpl implements ActivityService {

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private RedisCache redisCache;

    @Override
    public List<ActivityDTO> activityList(String actType) {
        return activityMapper.activityList(actType);
    }

    @Override
    public ActivityDTO findActivityById(Integer activityId) {
        ActivityDO activityDO = activityMapper.selectById(activityId);
        // 活动不存在则抛出异常
        if (activityDO == null) {
            throw new ActivityNoExitException();
        }
        ActivityDTO activityDTO = new ActivityDTO();
        BeanUtils.copyProperties(activityDO, activityDTO);
        return activityDTO;
    }

    @Override
    public List<ActivityInfoDTO> stuActivityList(Integer stuId) {
        return activityMapper.stuActivityList(stuId);
    }

    @Transactional(rollbackFor = {Exception.class})
    @Override
    public boolean signUpActivity(Integer activityId, Integer stuId) {
        // 1.检查用户有没有报名过，如果报名过直接抛出异常
        if (redisCache.existValueSet(activityId.toString(), stuId)) {
            throw new ActivityRepeatSignUpException();
        }
        // 2.查看报名时间有没有过期，如果过期直接抛出异常
        ActivityDO activityDO = activityMapper.selectById(activityId);
        if (activityDO == null) {
            throw new ActivityNoExitException();
        }
        if (activityDO.getEndTime().getTime() < System.currentTimeMillis()) {
            throw new ActivityOverException();
        }
        // 3.查看还有没有报名名额，如果没有直接抛出异常
        if (activityDO.getCur().equals(activityDO.getTotal())) {
            throw new ActivitySignUpFullException();
        }
        // 4.报名（使用version来修改数据）
        String version = activityDO.getVersion();
        Integer cur = activityDO.getCur();
        int flag = activityMapper.updateActivityInfo(activityId, version, version + 1, cur + 1);
        // 5.如果报名失败，则返回false
        if (flag <= 0) {
            throw new ActivitySignUpFailException();
        }
        // 6.如果报名成功，则添加报名记录表
        activityMapper.insertStuAct(activityId, stuId, new Date());

        // TODO 7.向消息队列发送信息
        return true;
    }
}
